// Hash Functions (哈希函数) 示例
// 演示 Pascal 中哈希函数的各种用法
program p_51_hash_functions;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,        // 系统工具单元
  Classes,         // 类单元
  MD5,             // MD5哈希算法
  SHA1,            // SHA-1哈希算法
  SHA256,          // SHA-256哈希算法
  SHA512;          // SHA-512哈希算法

// 基本哈希算法使用示例
procedure BasicHashAlgorithms;
var
  inputData: String;
  md5Digest: TMD5Digest;
  sha1Digest: TSHA1Digest;
  sha256Digest: TSHA256Digest;
  sha512Digest: TSHA512Digest;
begin
  WriteLn('1. 基本哈希算法使用:');
  
  inputData := 'Hello, Pascal Hash Functions!';
  WriteLn('  输入数据: "', inputData, '"');
  
  // MD5哈希
  md5Digest := MD5String(inputData);
  WriteLn('  MD5哈希: ', MD5DigestToStr(md5Digest));
  
  // SHA-1哈希
  sha1Digest := SHA1String(inputData);
  WriteLn('  SHA-1哈希: ', SHA1DigestToStr(sha1Digest));
  
  // SHA-256哈希
  sha256Digest := SHA256String(inputData);
  WriteLn('  SHA-256哈希: ', SHA256DigestToStr(sha256Digest));
  
  // SHA-512哈希
  sha512Digest := SHA512String(inputData);
  WriteLn('  SHA-512哈希: ', SHA512DigestToStr(sha512Digest));
  
  WriteLn;
  
  // 中文数据哈希
  inputData := '你好，Pascal哈希函数！';
  WriteLn('  中文输入数据: "', inputData, '"');
  
  md5Digest := MD5String(inputData);
  WriteLn('  MD5哈希: ', MD5DigestToStr(md5Digest));
  
  sha1Digest := SHA1String(inputData);
  WriteLn('  SHA-1哈希: ', SHA1DigestToStr(sha1Digest));
  
  sha256Digest := SHA256String(inputData);
  WriteLn('  SHA-256哈希: ', SHA256DigestToStr(sha256Digest));
  
  sha512Digest := SHA512String(inputData);
  WriteLn('  SHA-512哈希: ', SHA512DigestToStr(sha512Digest));
end;

// 字符串和文件的哈希计算示例
procedure StringAndFileHashCalculation;
var
  testString: String;
  md5Digest: TMD5Digest;
  sha256Digest: TSHA256Digest;
begin
  WriteLn('2. 字符串和文件的哈希计算:');
  
  // 字符串哈希计算
  testString := '这是一个用于哈希计算的测试字符串。它包含了一些特殊字符：!@#$%^&*()_+-={}[]|;:,.<>?';
  WriteLn('  测试字符串: "', testString, '"');
  
  md5Digest := MD5String(testString);
  WriteLn('  MD5哈希: ', MD5DigestToStr(md5Digest));
  
  sha256Digest := SHA256String(testString);
  WriteLn('  SHA-256哈希: ', SHA256DigestToStr(sha256Digest));
  
  WriteLn;
  
  // 空字符串哈希
  testString := '';
  WriteLn('  空字符串:');
  md5Digest := MD5String(testString);
  WriteLn('    MD5哈希: ', MD5DigestToStr(md5Digest));
  
  sha256Digest := SHA256String(testString);
  WriteLn('    SHA-256哈希: ', SHA256DigestToStr(sha256Digest));
  
  WriteLn;
  
  // 相似字符串的哈希（展示雪崩效应）
  var string1 := 'The quick brown fox jumps over the lazy dog';
  var string2 := 'The quick brown fox jumps over the lazy cog';
  
  WriteLn('  相似字符串的哈希（雪崩效应）:');
  WriteLn('    字符串1: "', string1, '"');
  WriteLn('    字符串2: "', string2, '"');
  
  var hash1 := MD5String(string1);
  var hash2 := MD5String(string2);
  
  WriteLn('    字符串1的MD5: ', MD5DigestToStr(hash1));
  WriteLn('    字符串2的MD5: ', MD5DigestToStr(hash2));
  
  // 计算差异位数
  var diffCount := 0;
  for var i := 0 to SizeOf(hash1) - 1 do
    if hash1[i] <> hash2[i] then
      Inc(diffCount);
  
  WriteLn('    差异字节数: ', diffCount, '/', SizeOf(hash1), ' (', 
          (diffCount / SizeOf(hash1) * 100):0:1, '%)');
end;

// 密码安全存储和验证示例
procedure PasswordSecurityStorageAndVerification;
var
  password: String;
  salt: String;
  saltedPassword: String;
  md5Hash: TMD5Digest;
  sha256Hash: TSHA256Digest;
begin
  WriteLn('3. 密码安全存储和验证:');
  
  password := 'MySecretPassword123!';
  WriteLn('  原始密码: "', password, '"');
  
  // 生成随机盐值（简化示例，实际应用中应使用真正的随机数）
  salt := 'RandomSalt2025';
  WriteLn('  盐值: "', salt, '"');
  
  // 加盐哈希
  saltedPassword := password + salt;
  md5Hash := MD5String(saltedPassword);
  WriteLn('  加盐MD5哈希: ', MD5DigestToStr(md5Hash));
  
  sha256Hash := SHA256String(saltedPassword);
  WriteLn('  加盐SHA-256哈希: ', SHA256DigestToStr(sha256Hash));
  
  WriteLn;
  
  // 密码验证示例
  WriteLn('  密码验证示例:');
  var inputPassword := 'MySecretPassword123!';
  var inputSaltedPassword := inputPassword + salt;
  var inputHash := SHA256String(inputSaltedPassword);
  
  WriteLn('    输入密码: "', inputPassword, '"');
  WriteLn('    计算哈希: ', SHA256DigestToStr(inputHash));
  WriteLn('    验证结果: ', BoolToStr(CompareMem(@inputHash, @sha256Hash, SizeOf(sha256Hash)), True));
  
  // 错误密码验证
  var wrongPassword := 'WrongPassword';
  var wrongSaltedPassword := wrongPassword + salt;
  var wrongHash := SHA256String(wrongSaltedPassword);
  
  WriteLn('    错误密码: "', wrongPassword, '"');
  WriteLn('    计算哈希: ', SHA256DigestToStr(wrongHash));
  WriteLn('    验证结果: ', BoolToStr(CompareMem(@wrongHash, @sha256Hash, SizeOf(sha256Hash)), True));
  
  WriteLn;
  
  // 多次哈希增强安全性（类似PKDBF2）
  WriteLn('  多次哈希增强安全性:');
  var iterations := 1000;
  var multiHashData := password + salt;
  
  for var i := 1 to iterations do
    multiHashData := SHA256DigestToStr(SHA256String(multiHashData));
  
  WriteLn('    迭代次数: ', iterations);
  WriteLn('    最终哈希: ', multiHashData);
end;

// HMAC（哈希消息认证码）使用示例
procedure HMACUsage;
var
  key: String;
  message: String;
begin
  WriteLn('4. HMAC（哈希消息认证码）使用:');
  
  key := 'SecretKey123';
  message := 'This is a message to be authenticated';
  
  WriteLn('  密钥: "', key, '"');
  WriteLn('  消息: "', message, '"');
  
  // 注意：标准FPC RTL中没有直接的HMAC实现
  // 这里展示HMAC的概念，实际应用中建议使用专门的加密库
  
  // 简化的HMAC实现概念（仅供演示）
  var innerKey := '';
  var outerKey := '';
  
  // 简化处理（实际HMAC更复杂）
  var combined := key + message;
  var hmacMD5 := MD5String(combined);
  var hmacSHA256 := SHA256String(combined);
  
  WriteLn('  简化HMAC-MD5: ', MD5DigestToStr(hmacMD5));
  WriteLn('  简化HMAC-SHA256: ', SHA256DigestToStr(hmacSHA256));
  
  WriteLn;
  WriteLn('  HMAC说明:');
  WriteLn('    - HMAC提供消息认证和完整性保护');
  WriteLn('    - 需要使用专门的加密库实现标准HMAC');
  WriteLn('    - 常用于API认证、数字签名等场景');
end;

// 哈希函数在实际应用中的使用示例
procedure PracticalHashApplications;
begin
  WriteLn('5. 哈希函数在实际应用中的使用:');
  
  // 数据完整性验证
  WriteLn('  数据完整性验证:');
  var originalFile := '重要文件内容数据';
  var fileHash := SHA256String(originalFile);
  WriteLn('    原始文件内容: "', originalFile, '"');
  WriteLn('    文件SHA-256哈希: ', SHA256DigestToStr(fileHash));
  
  // 模拟文件传输后验证
  var receivedFile := '重要文件内容数据';  // 假设传输无误
  var receivedHash := SHA256String(receivedFile);
  WriteLn('    接收文件内容: "', receivedFile, '"');
  WriteLn('    接收文件哈希: ', SHA256DigestToStr(receivedHash));
  WriteLn('    完整性验证: ', BoolToStr(CompareMem(@fileHash, @receivedHash, SizeOf(fileHash)), True));
  
  WriteLn;
  
  // 用户会话标识生成
  WriteLn('  用户会话标识生成:');
  var sessionData := 'UserID:12345|LoginTime:' + DateTimeToStr(Now) + '|IP:192.168.1.100';
  var sessionId := MD5String(sessionData);
  WriteLn('    会话数据: "', sessionData, '"');
  WriteLn('    会话ID(MD5): ', MD5DigestToStr(sessionId));
  
  WriteLn;
  
  // 缓存键生成
  WriteLn('  缓存键生成:');
  var cacheParams := 'Function:GetUserInfo|UserID:12345|IncludeDetails:true';
  var cacheKey := SHA1String(cacheParams);
  WriteLn('    缓存参数: "', cacheParams, '"');
  WriteLn('    缓存键(SHA-1): ', SHA1DigestToStr(cacheKey));
  
  WriteLn;
  
  // 唯一标识符生成
  WriteLn('  唯一标识符生成:');
  var uniqueData := 'Object:User|Property:Email|Value:user@example.com|Time:' + 
                    FormatDateTime('yyyymmddhhnnsszzz', Now);
  var uniqueId := SHA256String(uniqueData);
  WriteLn('    唯一数据: "', uniqueData, '"');
  WriteLn('    唯一标识符(SHA-256): ', Copy(SHA256DigestToStr(uniqueId), 1, 32), '...');
end;

// 哈希算法性能比较示例
procedure HashAlgorithmPerformanceComparison;
var
  testData: String;
  startTime, endTime: QWord;
  i: Integer;
begin
  WriteLn('6. 哈希算法性能比较:');
  
  // 生成测试数据
  testData := '';
  for i := 1 to 10000 do
    testData := testData + '这是第' + IntToStr(i) + '行测试数据。' + LineEnding;
  
  WriteLn('  测试数据大小: ', Length(testData), ' 字符');
  
  // MD5性能测试
  startTime := GetTickCount64;
  for i := 1 to 1000 do
    var md5Result := MD5String(testData);
  endTime := GetTickCount64;
  WriteLn('  MD5计算耗时: ', (endTime - startTime), ' 毫秒 (1000次)');
  
  // SHA-1性能测试
  startTime := GetTickCount64;
  for i := 1 to 1000 do
    var sha1Result := SHA1String(testData);
  endTime := GetTickCount64;
  WriteLn('  SHA-1计算耗时: ', (endTime - startTime), ' 毫秒 (1000次)');
  
  // SHA-256性能测试
  startTime := GetTickCount64;
  for i := 1 to 1000 do
    var sha256Result := SHA256String(testData);
  endTime := GetTickCount64;
  WriteLn('  SHA-256计算耗时: ', (endTime - startTime), ' 毫秒 (1000次)');
  
  // SHA-512性能测试
  startTime := GetTickCount64;
  for i := 1 to 1000 do
    var sha512Result := SHA512String(testData);
  endTime := GetTickCount64;
  WriteLn('  SHA-512计算耗时: ', (endTime - startTime), ' 毫秒 (1000次)');
  
  WriteLn;
  WriteLn('  哈希值长度比较:');
  WriteLn('    MD5: 128位 (32个十六进制字符)');
  WriteLn('    SHA-1: 160位 (40个十六进制字符)');
  WriteLn('    SHA-256: 256位 (64个十六进制字符)');
  WriteLn('    SHA-512: 512位 (128个十六进制字符)');
  
  WriteLn;
  WriteLn('  安全性建议:');
  WriteLn('    - MD5: 不推荐用于安全相关场景');
  WriteLn('    - SHA-1: 逐渐被淘汰，不推荐新项目使用');
  WriteLn('    - SHA-256: 目前推荐使用的标准算法');
  WriteLn('    - SHA-512: 更高安全要求时的选择');
end;

// 程序主入口
begin
  WriteLn('=== Pascal 哈希函数示例 ===');
  WriteLn;
  
  // 1. 基本哈希算法使用
  BasicHashAlgorithms;
  
  WriteLn;
  
  // 2. 字符串和文件的哈希计算
  StringAndFileHashCalculation;
  
  WriteLn;
  
  // 3. 密码安全存储和验证
  PasswordSecurityStorageAndVerification;
  
  WriteLn;
  
  // 4. HMAC（哈希消息认证码）使用
  HMACUsage;
  
  WriteLn;
  
  // 5. 哈希函数在实际应用中的使用
  PracticalHashApplications;
  
  WriteLn;
  
  // 6. 哈希算法性能比较
  HashAlgorithmPerformanceComparison;
  
  WriteLn;
  WriteLn('演示了 Pascal 中哈希函数的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.